/*
 * Copyright 2024 The JA-SIG Collaborative. All rights reserved.
 * distributed with thi file and available online at
 */
package com.lap.permission.service.impl;

import com.lap.framework.dto.page.Page;
import com.lap.framework.dto.page.PageDTO;
import com.lap.framework.enums.YesNo;
import com.lap.permission.convert.Convert;
import com.lap.permission.dal.DepartmentDAO;
import com.lap.permission.domain.entity.Department;
import com.lap.permission.dto.query.DepartmentQuery;
import com.lap.permission.dto.response.DepartmentDTO;
import com.lap.permission.service.DepartmentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@RequiredArgsConstructor
@Service
public class DepartmentServiceImpl implements DepartmentService {

    private final DepartmentDAO departmentDAO;

    private final Convert convert;

    @Override
    public PageDTO<List<Department>> queryPage(DepartmentQuery query) {
        long count = departmentDAO.countPage(query);
        if (count == 0) {
            return Page.ok(count);
        }
        return Page.ok(departmentDAO.queryPage(query), count);
    }

    @Override
    public List<DepartmentDTO> queryTree() {
        return getTree(departmentDAO.queryList());
    }

    private List<DepartmentDTO> getTree(List<Department> list) {
        if (CollectionUtils.isEmpty(list))
            return Collections.emptyList();

        List<DepartmentDTO> sources = list.stream()
                .map(convert::toDepartDto)
                .toList();
        List<DepartmentDTO> result = sources.stream()
                .filter(dept -> YesNo.NO.getValue().equals(dept.getPid()))
                .sorted(Comparator.comparing(DepartmentDTO::getOrders))
                .toList();

        for (DepartmentDTO deptDto : result) {
            getChildren(deptDto, sources, 0);
        }
        return result;
    }

    private DepartmentDTO getChildren(DepartmentDTO parent, List<DepartmentDTO> sources, int dept) {
        ++dept;
        if (dept >= 30) {
            log.warn("部门超过了深度:{}", dept);
            return parent;
        }

        for (DepartmentDTO deptDto : sources) {
            if (parent.getId().equals(deptDto.getPid())) {
                List<DepartmentDTO> child = parent.getChildren();
                if (Objects.isNull(child)) {
                    child = new ArrayList<>(sources.size());
                    parent.setChildren(child);
                }
                parent.getChildren().add(getChildren(deptDto, sources, dept));
                Collections.sort(parent.getChildren());
            }
        }
        return parent;
    }

    @Override
    public Department queryById(Integer departmentId) {
        return departmentDAO.queryById(departmentId);
    }

    @Override
    public List<Department> queryByPid(Integer pid) {
        return departmentDAO.queryByPid(pid);
    }

    @Override
    public Department queryByCode(String code) {
        return departmentDAO.queryByCode(code);
    }

    @Override
    public List<Department> queryByIds(List<Integer> list) {
        if (CollectionUtils.isEmpty(list))
            return Collections.emptyList();

        List<Integer> ids = list.stream().distinct().sorted().toList();
        return departmentDAO.queryByIds(ids);
    }

    @Override
    public Integer insertDepartment(Department department) {
        departmentDAO.insertDepartment(department);
        return department.getId();
    }

    @Override
    public int updateDepartment(Department department) {
        return departmentDAO.updateDepartment(department);
    }

    @Override
    public int deleteById(Integer departmentId) {
        return departmentDAO.deleteById(departmentId);
    }

}
